var connect = require('connect');

function logger(req, res, next) { // 总是调用next(), 所以后续中间件总会被调用
  console.log('%s %s', req.method, req.url);
  next();
}

function hello(req, res) { // 不会调用next(), 因为组件响应了请求
  res.setHeader('Content-Type', 'text/plain');
  res.end('hello world');
}

function restrict(req, res, next) { // 实现HTTP Basic认证的中间件组件
  var authorization = req.headers.authorization;
  if (!authorization) return next(new Error('Unauthorized'));

  var parts = authorization.split(' ');
  var scheme = parts[0];
  var auth = new Buffer(parts[1], 'base64').toString().split(':');
  var user = auth[0];
  var pass = auth[1];

  authenticateWithDatabase(user, pass, function(err) { // 根据数据库中的记录检查认证信息的函数
    if (err) return next(err); // 告诉分派器出错了
    next(); // 如果认证信息有效，不带参数调用next()
  });
}

function admin(req, res, next) { // 路由admin请求
  switch(req.url) {
    case '/':
      res.end('try /users');
      break;
    case '/users':
      res.setHeader('Content-Type', 'application/json');
      res.end(JSON.stringify(['tobi', 'loki', 'jane']));
      break;
  }
}

var app = connect()
            .use(logger)
            .use('/admin', restrict) // 当.use()的第一个参数是哥字符串时，只有URL前缀与之匹配时，Connect才会调用后面的中间件
            .use('/admin', admin)
            .use(hello)
            .listen(3000);

